package com.leihub.xlfiletools.excel.service;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ExcelService {

    private static final int DEFAULT_COLUMN_WIDTH = 14 * 256; // 默认宽度为14个字符

    public ByteArrayOutputStream generateExcelReport() throws IOException {
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            XSSFSheet sheet = workbook.createSheet("Transactions");

            // Mock 数据
            List<CreditCardTransaction> transactions = mockTransactions();
            List<CreditCardTransactionDetailByTime> details = mockTransactionDetails();
            List<CreditCardTransactionSummary> summaries = mockTransactionSummaries();

            String[] headers1 = {"日期", "交易类型", "交易金额"};
            createTable(sheet, transactions, headers1, 0);

            // 插入两行空白以分隔两个表
            int nextRowStart = transactions.size() + 2;

            String[] headers2 = {"日期", "交易ID", "金额", "详情"};
            createTable(sheet, details, headers2, nextRowStart);

            // 插入两行空白以分隔两个表
            nextRowStart += details.size() + 2;

            String[] headers3 = {"日期", "交易类型", "总金额"};
            createTable(sheet, summaries, headers3, nextRowStart);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream;
        }
    }

    private void createTable(XSSFSheet sheet, List<?> items, String[] headers, int startRow) {
        Workbook workbook = sheet.getWorkbook();
        CellStyle headerStyle = createCellStyle(workbook, IndexedColors.LIGHT_BLUE.getIndex(), true);
        CellStyle evenRowStyle = createCellStyle(workbook, IndexedColors.LIGHT_YELLOW.getIndex(), false);
        CellStyle oddRowStyle = createCellStyle(workbook, IndexedColors.LIGHT_TURQUOISE.getIndex(), false);
        CellStyle wrapTextStyle = workbook.createCellStyle();
        wrapTextStyle.setWrapText(true);

        // 设置默认列宽
        sheet.setDefaultColumnWidth(14);

        // 创建表头
        Row headerRow = sheet.createRow(startRow);
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
            sheet.setColumnWidth(i, DEFAULT_COLUMN_WIDTH); // 设置默认宽度
        }

        // 填充数据
        int rownum = startRow + 1;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (Object item : items) {
            Row row = sheet.createRow(rownum++);
            CellStyle rowStyle = (rownum % 2 == 0) ? evenRowStyle : oddRowStyle;
            if (item instanceof CreditCardTransaction transaction) {
                createCell(row, 0, dateFormat.format(transaction.getDate()), wrapTextStyle, rowStyle, sheet);
                createCell(row, 1, transaction.getTransactionType(), wrapTextStyle, rowStyle, sheet);
                createCell(row, 2, String.valueOf(transaction.getAmount()), wrapTextStyle, rowStyle, sheet);
            } else if (item instanceof CreditCardTransactionDetailByTime detail) {
                createCell(row, 0, dateFormat.format(detail.getDate()), wrapTextStyle, rowStyle, sheet);
                createCell(row, 1, detail.getTransactionId(), wrapTextStyle, rowStyle, sheet);
                createCell(row, 2, String.valueOf(detail.getAmount()), wrapTextStyle, rowStyle, sheet);
                createCell(row, 3, detail.getDetail(), wrapTextStyle, rowStyle, sheet);
            } else if (item instanceof CreditCardTransactionSummary summary) {
                createCell(row, 0, dateFormat.format(summary.getDate()), wrapTextStyle, rowStyle, sheet);
                createCell(row, 1, summary.getTransactionType(), wrapTextStyle, rowStyle, sheet);
                createCell(row, 2, String.valueOf(summary.getTotalAmount()), wrapTextStyle, rowStyle, sheet);
            }
        }
    }

    private void createCell(Row row, int colNum, String value, CellStyle wrapTextStyle, CellStyle rowStyle, XSSFSheet sheet) {
        Cell cell = row.createCell(colNum);
        cell.setCellValue(value);
        cell.setCellStyle(rowStyle);
        cell.getCellStyle().setWrapText(true); // 设置自动换行
        adjustColumnWidth(sheet, colNum, value);
    }

    private void adjustColumnWidth(XSSFSheet sheet, int colNum, String value) {
        int length = value.length();
        int width = length * 256;
        if (width > DEFAULT_COLUMN_WIDTH) {
            sheet.setColumnWidth(colNum, DEFAULT_COLUMN_WIDTH);
        }
    }

    private CellStyle createCellStyle(Workbook workbook, short color, boolean isBold) {
        CellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(color);
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font font = workbook.createFont();
        font.setBold(isBold);
        font.setColor(IndexedColors.BLACK.getIndex());
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    private List<CreditCardTransaction> mockTransactions() {
        List<CreditCardTransaction> transactions = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            transactions.add(new CreditCardTransaction(new Date(), "类型" + (i % 5), 1000.0 + i));
        }
        return transactions;
    }

    private List<CreditCardTransactionDetailByTime> mockTransactionDetails() {
        List<CreditCardTransactionDetailByTime> details = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            details.add(new CreditCardTransactionDetailByTime(new Date(), "ID" + i, 2000.0 + i, "详情" + i));
        }
        return details;
    }

    private List<CreditCardTransactionSummary> mockTransactionSummaries() {
        List<CreditCardTransactionSummary> summaries = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            summaries.add(new CreditCardTransactionSummary(new Date(), "类型" + (i % 5), 5000.0 + i));
        }
        return summaries;
    }
}

class CreditCardTransaction {
    private Date date;
    private String transactionType;
    private Double amount;

    public CreditCardTransaction(Date date, String transactionType, Double amount) {
        this.date = date;
        this.transactionType = transactionType;
        this.amount = amount;
    }

    public Date getDate() {
        return date;
    }

    public String getTransactionType() {
        return transactionType;
    }

    public Double getAmount() {
        return amount;
    }
}

class CreditCardTransactionDetailByTime {
    private Date date;
    private String transactionId;
    private Double amount;
    private String detail;

    public CreditCardTransactionDetailByTime(Date date, String transactionId, Double amount, String detail) {
        this.date = date;
        this.transactionId = transactionId;
        this.amount = amount;
        this.detail = detail;
    }

    public Date getDate() {
        return date;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public Double getAmount() {
        return amount;
    }

    public String getDetail() {
        return detail;
    }
}

class CreditCardTransactionSummary {
    private Date date;
    private String transactionType;
    private Double totalAmount;

    public CreditCardTransactionSummary(Date date, String transactionType, Double totalAmount) {
        this.date = date;
        this.transactionType = transactionType;
        this.totalAmount = totalAmount;
    }

    public Date getDate() {
        return date;
    }

    public String getTransactionType() {
        return transactionType;
    }

    public Double getTotalAmount() {
        return totalAmount;
    }
}
